#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<vector>
#include<string>
#include<queue>
#include<algorithm>
#include<numeric>
using namespace std;

int minCostConnectPoints(vector<vector<int>>& points) {
	int n = points.size();
	vector<bool> visited(n, false);
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> heap;
	heap.push({ 0,0 });
	int ret=0;
	while (!heap.empty())
	{
		auto [dis, index] = heap.top();
		heap.pop();
		if (visited[index])
			continue;
		visited[index] = true;
		ret += dis;
		for (int i = 0; i < n; i++)
		{
			if (visited[i])
				continue;
			int d = abs(points[index][0] - points[i][0]) + abs(points[index][1] - points[i][1]);
			heap.push({ d,i });
		}
	}
	return ret;
}
class UnionFind
{
	vector<int> parent;
public:
	UnionFind(int n)
	{
		parent.resize(n);
		iota(parent.begin(), parent.end(), 0);
	}
	int Find(int x)
	{
		if (x != parent[x])
		{
			parent[x] = Find(parent[x]);
		}
		return parent[x];
	}
	void Merge(int x, int y)
	{
		int fx = Find(x), fy = Find(y);
		if (fx == fy)
			return;
		parent[fx] = fy;
	}
};
bool equationsPossible(vector<string>& equations) {
	UnionFind uf(26);
	for (auto& s : equations)
	{
		if (s[1] == '=')
		{
			int x = s[0] - 'a', y = s[3] - 'a';
			uf.Merge(x, y);
		}
	}
	for (auto& s : equations)
	{
		if (s[1] == '!')
		{
			int x = s[0] - 'a', y = s[3] - 'a';
			if (uf.Find(x) == uf.Find(y))
				return false;
		}
	}
	return true;
}
int main()
{

	return 0;
}